package com.lzq.badminton.controller;

import com.lzq.badminton.Exception.SystemException;
import com.lzq.badminton.entity.User;
import com.lzq.badminton.enums.AppHttpCodeEnum;
import com.lzq.badminton.service.UserService;
import com.lzq.badminton.utils.SecurityUtils;
import com.lzq.community.domain.entity.Event;
import com.lzq.community.domain.entity.Page;
import com.lzq.community.domain.vo.Pager;
import com.lzq.community.domain.vo.ResponseResult;
import com.lzq.community.event.EventProducer;
import com.lzq.community.service.impl.FollowService;
import com.lzq.community.util.CommunityConstant;
import com.lzq.community.util.CommunityUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.annotations.Mapping;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.websocket.server.PathParam;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/follow")
public class FollowController implements CommunityConstant {

    @Autowired
    private FollowService followService;

    @Autowired
    private UserService userService;

    @Autowired
    private EventProducer eventProducer;

    @PostMapping(path = "/follow")
    public ResponseResult follow(@PathParam("entityType") int entityType, @PathParam("entityId") Long entityId) {
        User user = userService.getById(SecurityUtils.getUserId());

        followService.follow(user.getId(), entityType, entityId);

        // 触发关注事件
        Event event = new Event()
                .setTopic(TOPIC_FOLLOW)
                .setUserId(SecurityUtils.getUserId())
                .setEntityType(entityType)
                .setEntityId(entityId)
                .setEntityUserId(entityId);
        eventProducer.fireEvent(event);

        return ResponseResult.okResult();
    }

    @PostMapping(path = "/unfollow")
    public ResponseResult unfollow(@PathParam("entityType") int entityType, @PathParam("entityId") Long entityId) {
        User user = userService.getById(SecurityUtils.getUserId());

        followService.unfollow(user.getId(), entityType, entityId);

        return ResponseResult.okResult();
    }

    @GetMapping(path = "/followees/{userId}")
    public ResponseResult getFollowees(@PathVariable("userId") Long userId, int pageNum, int pageSize) {
        Pager<Map<String, Object>> page = new Pager<>();
        User user = userService.getById(userId);
        if (user == null) {
            throw new SystemException(AppHttpCodeEnum.USER_NOT_EXIT);
        }

        page.setPage(pageNum);
        page.setSize(pageSize);
        page.setTotal((int) followService.findFolloweeCount(userId, ENTITY_TYPE_USER));

        List<Map<String, Object>> userList = followService.findFollowees(userId, page.getOffset(), page.getSize());
        if (userList != null) {
            for (Map<String, Object> map : userList) {
                User u = (User) map.get("user");
                map.put("hasFollowed", hasFollowed(u.getId()));
            }
        }

        return ResponseResult.okResult(userList);
    }

    @GetMapping(path = "/followers/{userId}")
    public ResponseResult getFollowers(@PathVariable("userId") Long userId, int pageNum, int pageSize) {
        Pager<Map<String, Object>> page = new Pager<>();
        User user = userService.getById(userId);
        if (user == null) {
            throw new SystemException(AppHttpCodeEnum.USER_NOT_EXIT);
        }

        page.setPage(pageNum);
        page.setSize(pageSize);
        page.setTotal((int) followService.findFollowerCount(ENTITY_TYPE_USER, userId));

        List<Map<String, Object>> userList = followService.findFollowers(userId, page.getOffset(), page.getSize());
        if (userList != null) {
            for (Map<String, Object> map : userList) {
                User u = (User) map.get("user");
                map.put("hasFollowed", hasFollowed(u.getId()));
            }
        }

        return ResponseResult.okResult(userList);
    }

    private boolean hasFollowed(Long userId) {
        if (SecurityUtils.getUserId() == null) {
            return false;
        }

        return followService.hasFollowed(SecurityUtils.getUserId(), ENTITY_TYPE_USER, userId);
    }

}
